#ifndef FINAL_GUARD_HPP
#define FINAL_GUARD_HPP

#include <functional>
#include <QObject>
#include <QPointer>
#include <utility>

template<class Callable>
class FunctionGuard
{
public:
    /**
     * 对function进行封装，生成与QObject类型对象关联生命周期的回调函数
     * 当life对象结束生命周期后，function将不会再被调用
     * Ps: 这个思想是从Telegram/tdesktop源码的crl::guard_wrap借鉴来的
     * crl源码链接: https://github.com/telegramdesktop/crl/blob/master/src/crl/common/crl_common_on_main_guarded.h
     */
    FunctionGuard(QObject* life, Callable&& func) : _life(life), _func(std::forward<Callable>(func)) {}

    template <class... Args, class ReturnType = decltype (std::declval<Callable>()(std::declval<Args>()...))>
    ReturnType operator()(Args&& ...args)
    {
        if (_life)
            return _func(args...);
        return ReturnType();
    }
private:
    QPointer<QObject> _life;
    Callable _func;
};

class FinalGuard
{
public:
    FinalGuard(std::function<void()>&& finalExecute) : _finalExecute(std::forward<std::function<void()>>(finalExecute)) {}
    ~FinalGuard() {_finalExecute();}
private:
    std::function<void()> _finalExecute;
};



#endif
